package com.iot08.api.service;

import com.iot08.api.constant.Constant;
import com.iot08.api.response.RollTimeDataResp;
import com.iot08.common.entity.app.RollTimeData;
import com.iot08.common.service.base.BaseService;
import com.iot08.common.utils.DateUtil;
import com.iot08.common.utils.response.ResponseMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.bson.types.ObjectId;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author cwj
 * @description
 * @date 2025/5/11 9:05
 **/
@Slf4j
@Service
public class RollTimeDataService extends BaseService<RollTimeData> {


    /**
     * @description 保存或更新反翻滚次数信息
     * @author cwj
     * @param [imei, rollNum]
     * @return void
     * @date @time 2025/5/11 9:15
     **/
    public void saveOrUpdateRollTimeData(String imei,Integer rollNum){
        Date date = new Date();
        String dateStr = DateUtil.dateToStr(date,DateUtil.FORMAT_4);
        //查询今日有无上报记录，有则更新，无则插入
        RollTimeData rollTimeData = this.queryByImeiDate(imei,dateStr);
        if(ObjectUtils.isEmpty(rollTimeData)) {
            rollTimeData = new RollTimeData();
            rollTimeData.setRollNum(rollNum);
            rollTimeData.setDate(dateStr);
            rollTimeData.setImei(imei);
            rollTimeData.setSleepState(transferSleepStateByRollNum(rollNum));
            rollTimeData.setCreateTime(date.getTime()/1000);
            rollTimeData.setUpdateTime(date.getTime()/1000);
            //三个月后过期，统一由TTL索引清理
            rollTimeData.setExpiryAt(DateUtil.getSystemExpiryAt());
            this.save(rollTimeData);
        } else {
            Update update = new Update();
            update.set("rollNum",rollNum);
            update.set("sleepState",transferSleepStateByRollNum(rollNum));
            update.set("updateTime",date.getTime()/1000);
            this.updateById(new ObjectId(rollTimeData.getId()),update);
        }
    }
    
    /**
     * @description 查询指定日期的翻滚次数数据
     * @author cwj
     * @param [imei, dateStr]
     * @return com.iot08.common.entity.app.RollTimesData
     * @date @time 2025/5/11 9:29
     **/
    public RollTimeData queryByImeiDate(String imei,String dateStr) {
        Query query = new Query();
        query.addCriteria(Criteria.where("imei").is(imei).and("date").is(dateStr)).limit(1);
        return this.findOne(query);
    }


    /**
     * @description 查询设备一周内的数据
     * @author cwj
     * @param [imei]
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2025/5/11 11:11
     **/
    public ResponseMap queryRollTimeInfo(String imei){
        List<RollTimeDataResp> rollTimeDataResps = new ArrayList<>();
        Date endTime = new Date();
        long beforeTime = endTime.getTime()-7*24*60*60*1000;
        Date startTime = new Date(beforeTime);
        Query query = new Query();
        query.addCriteria(Criteria.where("date").gte(DateUtil.dateToStr(startTime,DateUtil.FORMAT_4)).lte(DateUtil.dateToStr(endTime,DateUtil.FORMAT_4))
                .and("imei").is(imei));
        query.with(Sort.by(Sort.Order.desc("date")));
        List<RollTimeData> rollTimeDatas = this.find(query);
        if(CollectionUtils.isEmpty(rollTimeDatas)) {
            for(int i=0;i<7;i++){
                String dateStr = DateUtil.dateToStr(new Date(endTime.getTime()-i*24*60*60*1000),DateUtil.FORMAT_9);
                RollTimeDataResp rollTimeDataResp = new RollTimeDataResp();
                assembleRollTimeDataResp(rollTimeDataResp, dateStr, 3, i, rollTimeDataResps);
            }
        } else {
           for(int i=0;i<7;i++){
               String dateStr = DateUtil.dateToStr(new Date(endTime.getTime()-i*24*60*60*1000),DateUtil.FORMAT_4);
               String monthDay = DateUtil.dateToStr(new Date(endTime.getTime()-i*24*60*60*1000),DateUtil.FORMAT_9);
               RollTimeDataResp rollTimeDataResp = new RollTimeDataResp();
               boolean isExists = false;
               for(int j=0;j<rollTimeDatas.size();j++){
                   RollTimeData rtd = rollTimeDatas.get(j);
                   if(dateStr.equals(rtd.getDate())){
                       //组装数据
                       assembleRollTimeDataResp(rollTimeDataResp, monthDay, rtd.getSleepState(), i, rollTimeDataResps);
                       isExists = true;
                       break;
                   }
               }
               if(!isExists) {
                   assembleRollTimeDataResp(rollTimeDataResp, monthDay, 3, i, rollTimeDataResps);
               }
           }
        }
        ResponseMap res = ResponseMap.success();
        res.put("sleepQualityCeriterion", Constant.SLEEP_QUALITY_CERITERION);
        res.put("rollTimeDataResps",rollTimeDataResps);
        return res;
    }

    /**
     * @description 设置
     * @author cwj
     * @param [rollTimeDataResp, monthDay, sleepState, i, rollTimeDataResps]
     * @return void
     * @date @time 2025/5/11 14:21
     **/
    private void assembleRollTimeDataResp(RollTimeDataResp rollTimeDataResp, String monthDay, Integer sleepState, int i, List<RollTimeDataResp> rollTimeDataResps) {
        rollTimeDataResp.setDate(monthDay);
        rollTimeDataResp.setSleepState(sleepState);
        if (i == 0) {
            rollTimeDataResp.setDesc("今日的睡眠质量");
        } else if (i == 1) {
            rollTimeDataResp.setDesc("昨日的睡眠质量");
        } else {
            rollTimeDataResp.setDesc(monthDay + "的睡眠质量");
        }
        rollTimeDataResps.add(rollTimeDataResp);
    }


    /**
     * @description 根据翻滚次数设置状态
     * @author cwj
     * @param [rollNum]
     * @return java.lang.Integer
     * @date @time 2025/5/11 9:24
     **/
    private Integer transferSleepStateByRollNum(Integer rollNum){
        int sleepState;
        if(rollNum<28){
            sleepState = 1;
        } else if(rollNum<=40){
            sleepState = 2;
        } else {
            sleepState = 0;
        }
        return sleepState;
    }

}
